﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using HotelManageSystem.Domain;
using HotelManageSystem.Domain.Entities;
using HotelManageSystem.Domain.Infrastructure;
using HotelManageSystem.Models;
using Microsoft.Web.Mvc;
using Telerik.Web.Mvc;

namespace HotelManageSystem.Controllers
{

    public class ClientController : Controller
    {
        //
        // GET: /Client/
        private readonly IClientRepository clientRepository;
        private readonly IClientTypeRepository clientTypeRepository;
        private readonly ICertificateTypeRepository certificateTypeRepository;
        private readonly IRoomRepository roomRepository;
        private readonly IRoomStateRepository roomStateRepository;
        private readonly IUnitOfWork unitOfWork;
        private readonly IProductRepository productRepository;
        private readonly IClientConsumptionRepository clientConsumptionRepository;
        private readonly IHotelingInfomationRepository hotelingRepository;
        public ClientController(IClientRepository clientRepository, IClientTypeRepository clientTypeRepository,
                                ICertificateTypeRepository certificateTypeRepository, IRoomRepository roomRepository,
                                IRoomStateRepository roomStateRepository, IProductRepository productRepository,
                                IClientConsumptionRepository clientConsumptionRepository, IHotelingInfomationRepository hotelingRepository, IUnitOfWork unitOfWork)
        {
            this.clientRepository = clientRepository;
            this.clientTypeRepository = clientTypeRepository;
            this.certificateTypeRepository = certificateTypeRepository;
            this.roomRepository = roomRepository;
            this.roomStateRepository = roomStateRepository;
            this.productRepository = productRepository;
            this.clientConsumptionRepository = clientConsumptionRepository;
            this.hotelingRepository = hotelingRepository;
            this.unitOfWork = unitOfWork;
        }



        public ActionResult DetailsInfo(string clientId)
        {
            clientId = Session["clientId"].ToString();
            var clientInfo = clientRepository.Get(x => x.ID == clientId);
            var model = new ClientInfoModel();
            model.ClientTypeName = clientInfo.ClientType.Name;
            model.CertificateTypeName = clientInfo.CertificateType.Name;
            ModelCopier.CopyModel(clientInfo, model);
            return View(model);
        }
        //修改客户HotelingInfomation信息
        public void UpdateClientInfo()
        {
            var client = clientRepository.Get(x => x.ID == Session["clientId"].ToString());
            client.HotelingInfomation = hotelingRepository.Get(x => x.ID == Session["hotelingInfomationId"].ToString());
            clientRepository.Update(client);
            unitOfWork.Commit();
            Session.Remove("hotelingInfomationId");
        }
        //填写入住单(添加入住客户）,向Client表中添加数据
        public ActionResult FillUpAForm(ClientInfoModel modle, FormCollection formCollection)
        {
            if (Request.HttpMethod == "POST")
            {
                ClientTypeDropDownList();
                CertificateTypeDropDownList();
                // var qq = Convert.ToInt32(Request["ClientType"]);
                if (ModelState.IsValid)
                {
                    var client = new Client();
                    ModelCopier.CopyModel(modle, client);
                    client.ID = Session["clientId"].ToString();
                    if (formCollection["sex"].ToString() == "男")
                    {
                        client.Sex = "男";
                    }
                    else
                    {
                        client.Sex = "女";
                    }
                    var clientTypeID = Convert.ToInt32(Request["ClientType"]);
                    client.ClientType = clientTypeRepository.Get(x => x.ID == clientTypeID);

                    var certificateTypeID = Convert.ToInt32(Request["CertificateType"]);
                    client.CertificateType = certificateTypeRepository.Get(x => x.ID == certificateTypeID);
                    client.Room = roomRepository.Get(x => x.ID == Session["roomId"].ToString());

                    clientRepository.Add(client);
                    unitOfWork.Commit();



                    /*^^^^^^^^^^^^^^^^^^^^^^^^^^向表HotelingInformation中插入数据^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
                    if (Session["number"].ToString() == "1")
                    {
                        var hotelingInfomation = new HotelingInfomation();
                        hotelingInfomation.ID = "ZFXX" + DateTime.Now;
                        hotelingInfomation.Room = roomRepository.Get(x => x.ID == Session["roomId"].ToString());
                        hotelingRepository.Add(hotelingInfomation);
                        hotelingInfomation.EntetTime = DateTime.Now;
                        hotelingInfomation.AdvancePayment = Convert.ToDecimal(formCollection["AdvancePayment"]);
                        //插入入住人数
                        hotelingInfomation.PresonNum = Convert.ToInt32(Request["numberOfClient"]);
                        double days = Convert.ToDouble(formCollection["HotelingDays"]);
                        hotelingInfomation.EndTime = DateTime.Now.AddDays(days);
                        unitOfWork.Commit();
                        Session["hotelingInfomationId"] = hotelingInfomation.ID;


                        //修改刚刚填写的客户信息，即加入入住信息
                        client.HotelingInfomation = hotelingInfomation;
                        clientRepository.Update(client);
                        unitOfWork.Commit();
                    }
                    else
                    {
                        UpdateClientInfo();
                    }
                    /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
                    return RedirectToAction("DetailsInfo");
                }

                return View();
            }
            else
            {
                int i = 1;
                Session["number"] = (Convert.ToInt32(Session["number"]) + i).ToString();//判断执行的次数
                Session["roomId"] = Request["roomId"];
                Session["roomTypeId"] = roomRepository.Get(x => x.ID == Session["roomId"].ToString()).RoomType.ID.ToString();
                Session["clientId"] = "KHBH" + DateTime.Now.ToLongDateString() + "-" + DateTime.Now.ToLongTimeString();
                ViewData["ClientTypeName"] = new SelectList(clientTypeRepository.GetAll().AsEnumerable(), "ID", "Name");
                ViewData["CertificateTypeName"] = new SelectList(certificateTypeRepository.GetAll().AsEnumerable(), "ID", "Name");
                ClientTypeDropDownList();
                CertificateTypeDropDownList();
                return View();
            }
        }

        //获得消费信息
        private IList<ClientConsumptionInfoModel> GetConsumeDetails()
        {
            string producIdStr = Request["productId"];
            string pruductCountStr = Request["productCounts"];
            Array producIDArray = producIdStr.Split(',');
            List<string> pruductCountArray = pruductCountStr.Split(',').ToList();
            List<Product> consumptions = new List<Product>();
            foreach (var id in producIDArray)
            {
                var product = productRepository.Get(x => x.ID == Convert.ToInt32(id));
                consumptions.Add(product);
            }
            int sum = 0;
            for (int i = 0; i < consumptions.Count; i++)
            {
                sum += Convert.ToInt32(pruductCountArray[i]) * (int)(consumptions[i].PriceOut);
            }
            TempData["SumAccount"] = sum.ToString();
            ViewBag.ConsumeDate = DateTime.Now;
            List<ClientConsumptionInfoModel> showProduct = (from product in consumptions
                                                            select new ClientConsumptionInfoModel
                                                                       {
                                                                           ProductID = product.ID,
                                                                           ProductName = product.Name,
                                                                           PriceOut = product.PriceOut,
                                                                           ConsumeDate = DateTime.Now,
                                                                           RoomId = Session["roomId"].ToString(),
                                                                           ProductCount =
                                                                               Convert.ToInt32(
                                                                                   pruductCountArray[
                                                                                       consumptions.IndexOf(product)]),
                                                                           ProductCost =
                                                                               product.PriceOut *
                                                                               Convert.ToInt32(
                                                                                   pruductCountArray[
                                                                                       consumptions.IndexOf(product)]),
                                                                           SumAccount = sum

                                                                       }).ToList();
            /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^向ClientConsumption表插入消费数据^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
            var clientConsumptions = clientConsumptionRepository.GetMany(x => x.Room.ID == Session["roomId"].ToString());
            decimal sumAccountBefore = 0;
            if(clientConsumptions.Count()!=0)
            {
                sumAccountBefore = clientConsumptions.ToList()[0].SumAccount;
            }
            //r的作用是为了不让消费信息的主键重复
            int r = 0;
            foreach (var clientConsumptionInfoModel in showProduct)
            {
                var clientConsumption = new ClientConsumption();
                clientConsumption.Product = productRepository.Get(x => x.ID == clientConsumptionInfoModel.ProductID);
                ModelCopier.CopyModel(clientConsumptionInfoModel, clientConsumption);
                clientConsumption.ID = "XF" + DateTime.Now.ToLongDateString() + "-" + DateTime.Now.ToLongTimeString() + r.ToString();
                clientConsumption.Room = roomRepository.Get(x => x.ID == Session["roomId"].ToString());
                clientConsumptionRepository.Add(clientConsumption);
                unitOfWork.Commit();
                r++;
            }
            if (clientConsumptions.Count() != 0)
            {
                //更新消费总价格
                var clientConsumptionNows =
                    clientConsumptionRepository.GetMany(x => x.Room.ID == Session["roomId"].ToString());
                decimal sumAccountNow = sumAccountBefore + sum;
                foreach (var clientConsumption in clientConsumptionNows)
                {
                    clientConsumption.SumAccount = sumAccountNow;
                    clientConsumptionRepository.Update(clientConsumption);
                    unitOfWork.Commit();
                }
            }
            /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

            /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^及时更新Product表中的货品数量^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
            List<string> productId = producIdStr.Split(',').ToList();
            for (int i = 0; i < producIDArray.Length;i++ )
            {
                var product = productRepository.Get(x => x.ID ==Convert.ToInt32(productId[i]));
                product.Count = product.Count - Convert.ToInt32(pruductCountArray[i]);
                productRepository.Update(product);
                unitOfWork.Commit();
            }
            /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
            return showProduct;
        }

        public ActionResult ClientConsumeShow(ClientConsumptionInfoModel model)
        {
            return View(GetConsumeDetails());
        }

        [GridAction]
        public ActionResult TeletrikAjax()
        {
            return View(new GridModel(GetConsumeDetails()));
        }

        //更改消费信息
        [GridAction]
        public ActionResult UpdateConsumeInfo(int ID, int ProductCount)
        {
            return View();
        }

        //绑定客户类型下拉列表框
        public void ClientTypeDropDownList(object selectedUserType = null)
        {
            var clientType = clientTypeRepository.GetAll();
            ViewData["ClientType"] = new SelectList(clientType, "ID", "Name", selectedUserType);
        }

        //绑定证件类型下拉列表框
        public void CertificateTypeDropDownList(object selectedUserType = null)
        {
            var clientType = certificateTypeRepository.GetAll();
            ViewData["CertificateType"] = new SelectList(clientType, "ID", "Name", selectedUserType);
        }



        [HttpPost]
        public void CheckIn()
        {
            Session.Remove("number");
            var room = roomRepository.Get(x => x.ID == Session["roomId"].ToString());
            if (room != null)
            {
                room.RoomState = roomStateRepository.Get(x => x.ID == 2);
                roomRepository.Update(room);
                unitOfWork.Commit();

            }

        }

        [HttpPost]
        public void Book()
        {
            Session.Remove("number");
            var room = roomRepository.Get(x => x.ID == Session["roomId"].ToString());
            if (room != null)
            {
                room.RoomState = roomStateRepository.Get(x => x.ID == 5);
                roomRepository.Update(room);
                unitOfWork.Commit();

            }
        }

        #region 对客户信息进行操作

        public List<ClientInfoModel> GetAllClientInfo()
        {
            var clients = clientRepository.GetAll().AsQueryable();
            List<ClientInfoModel> lists = (from client in clients
                                           select new ClientInfoModel
                                                      {
                                                          ID = client.ID,
                                                          Name = client.Name,
                                                          ClientTypeName = client.ClientType.Name,
                                                          Sex = client.Sex,
                                                          CertificateTypeName = client.CertificateType.Name,
                                                          CertID = client.CertID,
                                                          Address = client.Address,
                                                          PresentAddress = client.PresentAddress,
                                                          Telphone = client.Telphone,
                                                          Vocation = client.Vocation,
                                                          CompanyName = client.CompanyName,
                                                          Birthday = client.Birthday,
                                                          AdvancePayment = client.AdvancePayment,
                                                          HotelingDays = client.HotelingDays,
                                                          IsCheckOut = client.IsCheckOut,
                                                          IsFreeze = client.IsFreeze,
                                                          Memo = client.Memo
                                                      }).ToList();
            return lists;
        }
        public ActionResult ShowAllClientInfo()
        {
            GetValue();
            return View(GetAllClientInfo());
        }
        [GridAction]
        public ActionResult ShowAllClientInfoAjax()
        {
            GetValue();
            return View(new GridModel(GetAllClientInfo()));
        }
        [GridAction]
       public ActionResult UpdateClient(string Id, string Name, int ClientTypeName, string Sex, int CertificateTypeName, string CertID, string Address, string PresentAddress, string Telphone, string Vocation, string CompanyName, DateTime Birthday, decimal AdvancePayment, int HotelingDays, bool IsFreeze)
        {
            var client = clientRepository.Get(x => x.ID == Id);
            client.Name = Name;
            client.ClientType = clientTypeRepository.Get(x => x.ID == ClientTypeName);
            client.Sex = Sex;
            client.CertificateType = certificateTypeRepository.Get(x => x.ID == CertificateTypeName);
            client.CertID = CertID;
            client.Address = Address;
            client.PresentAddress = PresentAddress;
            client.Telphone = Telphone;
            client.Vocation = Vocation;
            client.CompanyName = CompanyName;
            client.Birthday = Birthday;
            client.AdvancePayment = AdvancePayment;
            client.HotelingDays = HotelingDays;
            client.IsFreeze = IsFreeze;
            
            clientRepository.Update(client);
            unitOfWork.Commit();

            return View(new GridModel(GetAllClientInfo()));

        }

        [GridAction]
        public ActionResult DeleteClient(string Id)
        {
            var client = clientRepository.Get(x => x.ID == Id);
            if (client != null)
            {
                clientRepository.Delete(client);
                unitOfWork.Commit();
            }
            return View(new GridModel(GetAllClientInfo()));
        }

        public void GetValue()
        {
            ViewData["clientTypeNames"] = clientTypeRepository.GetAll().ToList();
            ViewData["certificateTypeNames"] = certificateTypeRepository.GetAll().ToList();
        }
    }
        #endregion
}
